package top.fwpsl.java.util.funcion;

import top.fwpsl.data.Data;
import top.fwpsl.data.PersonModel;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * 函数式接口
 * （1） 只包含一个抽象方法的接口。
 * （2） 通过 Lambda 表达式来创建该接口的对象
 * （3） 可以在任意函数式接口上使用 @FunctionalInterface 注解，
 *      这样做可以检测它是否是一个函数式接口，同时 javadoc 也会包含一条声明，说明这个接口是一个函数式接口
 *
 * 函数式接口的实例可以通过 lambda 表达式、方法引用来创建。
 * 任何用 方法引用 的地方都可由lambda表达式替换，
 * 但并不是所有的lambda表达式都可以用方法引用来替换。
 *
 * @author 风戏fw
 */
public class Demo {

    public static void main(String[] args) {
        PersonModel luJunYi = new PersonModel("lu jun yi", 35, "男");

        //Predicate 判断条件
        //找出卢俊义
        test_predicate(Predicate.isEqual(luJunYi));
        System.out.println();
        //找出年龄大于等于35岁的人
        test_predicate(predicat -> predicat.getAge() >= 35);
        System.out.println();
        //找出年龄大于等于35岁的女性
        Predicate<PersonModel> predicate = pre -> pre.getAge() >= 35;
        test_predicate(predicate.and(pre -> "女".equals(pre.getSex())));
        System.out.println();

        //Supplier 生成（传递）对象
        //参数传递
        test_supplier(() -> luJunYi);
        System.out.println();

        //Function 执行过程，数据整理
        test_function(person -> "我叫" + person.getName() + ", 今年" + person.getAge() + "岁。");
        System.out.println();

        //Consumer 执行过程
        test_consumer(person -> System.out.println("我是" + person.getSex() + "的"));
    }

    private static void test_predicate(Predicate<PersonModel> predicate) {
        Data.getDate().stream().filter(predicate).forEach(personModel -> System.out.println(personModel));
    }

    private static void test_supplier(Supplier<PersonModel> supplier) {
        System.out.println(supplier.get());
    }

    private static void test_function(Function<PersonModel, String> function) {
        Data.getDate().forEach(person ->
                System.out.println(function.apply(person)));
    }

    private static void test_consumer(Consumer<PersonModel> consumer) {
        Data.getDate().forEach(person -> consumer.accept(person));
    }

}
